from fastapi import APIRouter, Depends, Path, HTTPException, UploadFile, File, Request
from typing import List
from service.sysRoleService import SysRoleService
from service.sysDeptService import SysDeptService
from service.sysRoleDeptService import SysRoleDeptService
from service.sysUserService import SysUserService
from service.sysUserRoleService import SysUserRoleService
from schema.sysRoleSchema import SysRoleCreate, SysRoleUpdate, PageParams, RoleChange, RoleData, RoleAuth, RoleAuths
from utils.response import ResponseUtil, ResponseModel
from urllib.parse import quote
from fastapi.responses import StreamingResponse
from datetime import datetime
from io import BytesIO
from schema.sysUserSchema import PageParams as UserPageParams

router = APIRouter(prefix="/sysRole", tags=["角色信息表"])
service = SysRoleService()
dept_service = SysDeptService()
role_dept_service = SysRoleDeptService()
user_service = SysUserService()
user_role_service = SysUserRoleService()


@router.post(
    "",
    response_model=ResponseModel,
    summary="新增角色信息表",
    description="创建一个新的角色信息表。",
    response_description="返回创建成功的信息"
)
async def create(data: SysRoleCreate, request: Request):
    """新增角色信息表"""
    current_user = request.state.user
    creator = current_user["username"]
    result = await service.create(data, creator)
    return ResponseUtil.success(data=result, msg="创建成功")


@router.get(
    "/get/{id}",
    response_model=ResponseModel,
    summary="获取角色信息表详情",
    description="根据ID获取角色信息表的详细信息",
    response_description="返回角色信息表的详细信息"
)
async def get_detail(id: int):
    """获取角色信息表详情"""
    result = await service.get_by_id(id)
    return ResponseUtil.success(data=result)


@router.patch(
    "/update/{id}",
    response_model=ResponseModel,
    summary="更新角色信息表",
    description="更新指定ID的角色信息表信息。支持部分字段更新。",
    response_description="返回更新后的信息"
)
async def update(id: int, data: SysRoleUpdate, request: Request):
    """更新角色信息表"""
    current_user = request.state.user
    updater = current_user["username"]
    result = await service.update(id, data, updater)
    return ResponseUtil.success(data=result, msg="更新成功")


@router.delete(
    "/batch/{ids}",
    response_model=ResponseModel,
    summary="批量删除角色信息表",
    description="根据ID删除角色信息表，支持多个ID(用逗号分隔)。此操作不可恢复，请谨慎操作。",
    response_description="返回成功删除的数量"
)
async def delete(request: Request, ids: str = Path(..., description="ID，多个用逗号分隔，如：1,2,3")):
    """批量删除角色信息表"""
    try:
        id_list = [int(id.strip()) for id in ids.split(",")]
    except ValueError:
        raise ResponseUtil.error(code=400, msg="无效的ID格式")

    current_user = request.state.user
    updater = current_user["username"]
    count = await service.delete(id_list, updater)
    return ResponseUtil.success(data={"count": count}, msg=f"成功删除{count}条数据")


@router.get(
    "/page",
    response_model=ResponseModel,
    summary="分页查询角色信息表列表",
    description="分页获取角色信息表列表，支持多条件查询",
    response_description="返回分页数据，包含列表数据、总数、页码、每页大小"
)
async def get_page(
    params: PageParams = Depends()
):
    """分页获取角色信息表列表"""
    records, total = await service.get_page(params)
    return ResponseUtil.success(data={
        "records": records,
        "total": total,
        "page": params.page_num,
        "limit": params.page_size
    })


@router.get(
    "/export",
    summary="导出角色信息表数据",
    description="导出所有角色信息表数据到Excel文件",
    response_description="返回Excel文件"
)
async def export_data():
    """导出数据到Excel"""
    excel_data = await service.export_excel()

    filename = f"角色信息表数据_{datetime.now().strftime('%Y%m%d%H%M%S')}.xlsx"
    encoded_filename = quote(filename)

    headers = {
        'Content-Disposition': f'attachment; filename="{encoded_filename}"; filename*=utf-8\'\'{encoded_filename}',
        'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    }

    return StreamingResponse(
        BytesIO(excel_data.getvalue()),
        headers=headers,
        media_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    )


@router.get(
    "/importTemplate",
    summary="下载角色信息表导入模板",
    description="下载角色信息表导入的Excel模板文件",
    response_description="返回Excel模板文件"
)
async def get_import_template():
    """获取导入模板"""
    template_data = service.get_import_template()
    filename = f"角色信息表导入模板_{datetime.now().strftime('%Y%m%d%H%M%S')}.xlsx"
    encoded_filename = quote(filename)

    headers = {
        'Content-Disposition': f'attachment; filename="{encoded_filename}"; filename*=utf-8\'\'{encoded_filename}',
        'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    }

    return StreamingResponse(
        BytesIO(template_data.getvalue()),
        headers=headers,
        media_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    )


@router.post(
    "/import",
    response_model=ResponseModel,
    summary="导入角色信息表数据",
    description="通过Excel文件批量导入角色信息表数据",
    response_description="返回导入结果，包括成功数量和错误信息"
)
async def import_data(
    file: UploadFile = File(..., description="Excel文件")
):
    """导入数据"""
    if not file.filename.endswith(('.xls', '.xlsx')):
        return ResponseUtil.error(msg="只支持Excel文件格式（.xls, .xlsx）")

    creator = "admin"

    try:
        success_count, error_msgs = await service.import_data(file, creator)
        return ResponseUtil.success(data={
            "successCount": success_count,
            "errorMsgs": error_msgs
        }, msg=f"成功导入{success_count}条数据")
    except HTTPException as e:
        return ResponseUtil.error(msg=str(e.detail))
    except Exception as e:
        return ResponseUtil.error(msg=f"导入失败: {str(e)}")


@router.get(
    "/deptTree/{role_id}",
    response_model=ResponseModel,
    summary="获取角色信息和部门所有列表树形结构",
    description="获取角色信息和部门所有列表树形结构",
    response_description="返回角色信息和部门表树形结构"
)
async def get_role_and_dept(role_id: int, request: Request):
    """获取部门表详情"""
    current_user = request.state.user
    user_id = current_user["user_id"]
    dept_tree = await dept_service.get_dept_tree(user_id)
    dept_id_list = await role_dept_service.find_check_role_dept(role_id)
    result = {
        "depts": dept_tree,
        "checkedKeys": dept_id_list
    }
    return ResponseUtil.success(data=result)


@router.patch(
    "/changeStatus",
    response_model=ResponseModel,
    summary="更新角色状态",
    description="更新指定ID的角色状态",
    response_description="返回更新后的角色信息"
)
async def change_status(role: RoleChange, request: Request):
    """更新角色状态"""
    current_user = request.state.user
    updater = current_user["username"]
    result = await service.change_status(role, updater)
    return ResponseUtil.success(data=result, msg="更新角色成功")


@router.patch(
    "/dataScope",
    response_model=ResponseModel,
    summary="更新角色数据权限",
    description="更新指定ID的更新角色数据权限",
    response_description="返回更新后的角色信息"
)
async def data_scope(role: RoleData, request: Request):
    """更新角色数据权限"""
    current_user = request.state.user
    updater = current_user["username"]
    result = await service.save_data_scope(role, updater)
    return ResponseUtil.success(data=result, msg="更新角色成功")


@router.get(
    "/authUser/allocatedList",
    response_model=ResponseModel,
    summary="获取角色授权用户分页数据",
    description="获取角色授权用户分页数据",
    response_description="返回用户分页数据"
)
async def get_auth_alloc(params: UserPageParams = Depends()):
    """获取部门表详情"""
    params.is_allocated = 1
    records, total = await user_service.get_user_page(params)
    return ResponseUtil.success(data={
        "records": records,
        "total": total,
        "page": params.page_num,
        "limit": params.page_size
    })


@router.get(
    "/authUser/unallocatedList",
    response_model=ResponseModel,
    summary="获取角色未授权用户分页数据",
    description="获取角色未授权用户分页数据",
    response_description="返回用户分页数据"
)
async def get_auth_un_alloc(params: UserPageParams = Depends()):
    """获取部门表详情"""
    params.is_un_allocated = 1
    records, total = await user_service.get_user_page(params)
    return ResponseUtil.success(data={
        "records": records,
        "total": total,
        "page": params.page_num,
        "limit": params.page_size
    })


@router.patch(
    "/authUser/cancel",
    response_model=ResponseModel,
    summary="取消用户的角色授权",
    description="取消指定ID的用户的角色授权",
    response_description="返回更新后的角色信息"
)
async def cancel_auth(role_auth: RoleAuth):
    """取消用户的角色授权"""
    await user_role_service.cancel_auth_by_user(role_id=role_auth.role_id, user_id=role_auth.user_id)
    return ResponseUtil.success(data=role_auth, msg="更新角色成功")


@router.patch(
    "/authUser/cancelAll",
    response_model=ResponseModel,
    summary="批量取消用户的角色授权",
    description="批量取消用户的角色授权",
    response_description="返回更新后的角色信息"
)
async def cancel_auth_list(role_auths: RoleAuths):
    """取消用户的角色授权"""
    await user_role_service.cancel_auth_by_user_ids(role_id=role_auths.role_id, user_ids=role_auths.user_ids)
    return ResponseUtil.success(data=role_auths, msg="更新角色成功")


@router.patch(
    "/authUser/selectAll",
    response_model=ResponseModel,
    summary="批量授权用户的角色",
    description="批量授权用户的角色",
    response_description="返回更新后的角色信息"
)
async def select_auth_list(role_auths: RoleAuths, request: Request):
    """批量授权用户的角色"""
    current_user = request.state.user
    creator = current_user["username"]

    user_ids = role_auths.user_ids
    user_id_list = [int(user_id.strip()) for user_id in user_ids.split(",")]
    await user_role_service.batch_create_by_users(role_id=role_auths.role_id, user_id_list=user_id_list, creator=creator)
    return ResponseUtil.success(data=role_auths, msg="更新角色成功")
